<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PFLlib</title>
    <link rel="icon" href="imgs/logo-green.png" type="image/x-icon">
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            line-height: 1.6;
            background-color: #f4f4f4;
            color: #333333;
            display: flex;
            flex-direction: column;
            min-height: 100vh;
        }
        .navbar {
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 1rem 0rem;
            position: fixed;
            width: 100%;
            z-index: 1000;
            transition: background-color 0.3s ease;
            height: 2rem;
        }
        .navbar.scrolled {
            background-color: rgba(0, 0, 0, 0.7);
        }
        .navbar-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 100%;
            max-width: 1200px;
        }
        .navbar h1 {
            margin: 0;
            color: white;
        }
        .navbar nav {
            display: flex;
            gap: 1rem;
        }
        .navbar a {
            color: white;
            text-decoration: none;
            transition: color 0.3s ease;
            padding: 0rem 1rem;
        }
        .navbar a:hover {
            color: #6DA945;
        }
        .container {
            max-width: 1200px;
            margin: 8rem auto 2rem; /* Adjusted margin for container */
            padding: 0 2rem;
            flex-grow: 1; /* Ensures container takes up remaining space */
            display: flex;
        }
        .sidebar {
            width: 15rem;
            padding-right: 2rem;
            box-sizing: border-box;
        }
        .sidebar ul {
            list-style-type: none;
            padding: 0;
        }
        .sidebar li {
            margin-bottom: 0.5rem;
        }
        .sidebar a {
            color: #6DA945;
            text-decoration: none;
            font-weight: bold;
            transition: color 0.3s ease;
        }
        .sidebar a:hover {
            color: #2c6307;
        }
        .content {
            width: 75%;
            box-sizing: border-box;
        }
        h1, h2, h3 {
            color: #333333;
        }
        section {
            margin-bottom: 2rem;
        }
        pre {
            background-color: #f9f9f9;
            padding: 1rem;
            border-radius: 5px;
            overflow-x: auto;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        code {
            font-family: "Courier New", Courier, monospace;
            background-color: #f5f5f5;
            border-radius: 3px;
            padding: 2px 4px;
            color: #6DA945;
            font-weight: bold;
            font-weight: bold;
        }
        pre {
            font-family: "Courier New", Courier, monospace;
            background-color: #f5f5f5;
        }
        footer {
            background-color: #333;
            color: white;
            text-align: center;
            padding: 1rem 0;
            position: relative;
            width: 100%;
        }
        html {
            scroll-padding-top: 4.5rem; /* Adjust to the height of your navbar */
        }
        a {
            text-decoration: none;
            color: #6DA945;
        }
        .arxiv-badge {
            margin: 2rem;
        }
        .structure {
            object-fit: contain;
        }

        .hamburger {
            display: none;
            background: none;
            border: none;
            cursor: pointer;
            padding: 0.5rem;
            position: absolute;
            right: 1rem;
        }

        .hamburger span {
            display: block;
            width: 20px;
            height: 3px;
            background: white;
            margin: 5px 0;
            transition: 0.3s;
        }

        @media (max-width: 768px) {
            .container {
                max-width: 100%;
                flex-direction: column;
                margin-top: 6rem;
            }
            .sidebar, .content {
                width: 100%;
            }

            .navbar-container {
                flex-direction: row;
                flex-wrap: wrap;
            }

            .hamburger {
                display: block;
            }

            .navbar nav {
                display: none;
                flex-direction: column;
                width: 100%;
                background: #333333;
                padding: 1rem;
                margin-top: 2rem;
            }

            .navbar nav.active {
                display: flex;
            }
        }
    </style>
</head>
<body>
    <div class="navbar">
        <div class="navbar-container">
            <h1><img src="imgs/logo-green.png" alt="icon" height="36" style="vertical-align: sub; margin-left: 10pt;"/><a href="index.html" id="PFLlib">PFLlib</a></h1>
            <button class="hamburger" aria-label="Menu">
                <span></span>
                <span></span>
                <span></span>
            </button>
            <nav>
                <a href="index.html">Home</a>
                <a href="docs.html">Documentation</a>
                <a href="benchmark.html">Benchmark</a>
                <a href="about.html">About</a>
                <a href="https://github.com/TsingZ0/PFLlib" id="github-stars" class="github-stars">★ Star 1500</a>
            </nav>
        </div>
    </div>
    <div class="container">
        <div class="sidebar">
            <ul>
                <li><a href="quickstart.html">Quick Start</a></li>
                <li><a href="algo.html">FL Algorithms</a></li>
                <li><a href="data.html">Datasets & Scenarios</a></li>
                <li><a href="model.html">Models</a></li>
                <li><a href="extend.html">Easy to Extend</a></li>
                <li><a href="features.html">Other Features</a></li>
            </ul>
        </div>
        <div class="content">
            <section id="introduction">
                <h2>Introduction</h2>
                <a href="https://arxiv.org/abs/2312.04992">
                    <img src="https://img.shields.io/badge/arXiv-2312.04992-b31b1b.svg" alt="arXiv Badge">
                </a>
                <a href="http://www.apache.org/licenses/LICENSE-2.0">
                    <img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="Apache License 2.0" />
                </a>
                <br/>

                <p>The origin of the <strong>data heterogeneity</strong> phenomenon is the characteristics of users, who generate non-IID (not Independent and Identically Distributed) and unbalanced data. With data heterogeneity existing in the FL scenario, a myriad of approaches have been proposed to crack this hard nut. In contrast, the personalized FL (pFL) may take advantage of the statistically heterogeneous data to learn the personalized model for each user.</p>


                <h4>Simple File Structure</h4>
                <img src="imgs/structure.png" alt="PFLlib File Structure" width=100%>
                <p>An Example for FedAvg. You can create a scenario using <code>generate_DATA.py</code> and run an algorithm using <code>main.py</code>, <code>clientNAME.py</code>, and <code>serverNAME.py</code>. For a new algorithm, you only need to add new features in <code>clientNAME.py</code> and <code>serverNAME.py</code>.</p>
                
                <h4>Key Features</h4>
                <p>
                    <li><strong>38</strong> traditional FL (tFL) or personalized FL (pFL) algorithms,  <strong>3</strong> scenarios, and <strong>24</strong> datasets.</li>
                    <li>Some experimental results are avalible in the <a href="https://arxiv.org/abs/2312.04992"><strong>PFLlib paper</strong></a> and <a href="benchmark.html"><strong>Benchmark Results</strong></a>.</li>
                    <li>The benchmark platform can simulate scenarios using the 4-layer CNN on Cifar100 for <strong>500 clients</strong> on one NVIDIA GeForce RTX 3090 GPU card with <strong>only 5.08GB GPU memory cost</strong>.</li>
                    <li>We provide <a href="features.html#privacy-evaluation">privacy evaluation</a> and <a href="features.html#systematical-research-supprot">systematical research support</a>.</li>
                    <li>You can now train on some clients and evaluate performance on new clients by setting <code>args.num_new_clients</code> in <code>./system/main.py</code>. Please note that not all tFL/pFL algorithms support this feature.</li>
                    <li>PFLlib primarily focuses on data (statistical) heterogeneity. For algorithms and a benchmark platform that address <strong>both data and model heterogeneity</strong>, please refer to our extended project <a href="https://github.com/TsingZ0/HtFLlib"><strong>HtFLlib</strong></a>.</li>
                    <li>As we strive to meet diverse user demands, frequent updates to the project may alter default settings and scenario creation codes, affecting experimental results.</li>
                    <li><a href="https://github.com/TsingZ0/PFLlib/issues?q=is%3Aissue+is%3Aclosed"><strong>Closed issues</strong></a> may help you a lot when errors arise.</li>
                </p>
            </section>
            <section id="ack">
                <h2>Acknowledgement</h2>
                <p>If you find our PFLlib useful, please cite its corresponding paper</p>
                <pre>
@article{zhang2023pfllib,
    title={PFLlib: A Beginner-Friendly and Comprehensive Personalized Federated Learning Library and Benchmark},
    author={Zhang, Jianqing and Liu, Yang and Hua, Yang and Wang, Hao and Song, Tao and Xue, Zhengui and Ma, Ruhui and Cao, Jian},
    journal={arXiv preprint arXiv:2312.04992},
    year={2023}
}</pre>
            </section>
        </div>
    </div>
    <footer>
        <p>&copy; 2025 PFLlib. All rights reserved.</p>
    </footer>
    <script>
        window.addEventListener('scroll', function() {
            const navbar = document.querySelector('.navbar');
            if (window.scrollY > 50) {
                navbar.classList.add('scrolled');
            } else {
                navbar.classList.remove('scrolled');
            }
        });

        async function fetchGitHubStars() {
            try {
                const response = await fetch('https://api.github.com/repos/TsingZ0/PFLlib');
                if (!response.ok) throw new Error('Network response was not ok');
                const data = await response.json();
                document.getElementById('github-stars').textContent = `★ Star ${data.stargazers_count}`;
            } catch (error) {
                console.error('Failed to fetch GitHub stars:', error);
                document.getElementById('github-stars').textContent = '★ Star 1500';
            }
        }
        fetchGitHubStars();

        document.querySelector('.hamburger').addEventListener('click', function() {
            this.classList.toggle('active');
            document.querySelector('.navbar nav').classList.toggle('active');
        });

        document.addEventListener('click', function(e) {
            if (!e.target.closest('.navbar-container')) {
                document.querySelector('.navbar nav').classList.remove('active');
                document.querySelector('.hamburger').classList.remove('active');
            }
        });
    </script>
</body>
</html>
